from dataclasses import asdict

from firstDjango.exceptions import FormException
from index.common.paging import page2offset
from index.common.tool import get_current_domain_name, nround, get_url
from index.dao import books_dao, comment_dao
from index.protocol.book_protocol import Book, BookUpdateInfo


def add_book(book: Book):
    pub_id = books_dao.get_or_create_pub(book.pub)

    book_dict = asdict(book)
    book_dict.pop('pub')
    book_dict['pub_id'] = pub_id

    book_dict.pop("authors")

    authors = books_dao.get_authors_by_names(book.authors.split(','))

    book_model = books_dao.add_book(book_dict)
    book_model.authors.add(*authors)
    return book_model.id


# 删除书信息
def delete_book(book_id):
    books_dao.delete_book(book_id)


# 修改书信息
def update_book_info(book: BookUpdateInfo):
    book_dict = asdict(book)
    book_dict.pop("pub")
    book_dict.pop("authors")
    if book.pub is not None:
        pub_id = books_dao.get_or_create_pub(book.pub)
        book_dict["pub_id"] = pub_id

    no_none_dict = {}
    for k, v in book_dict.items():
        if v is not None:
            no_none_dict[k] = v

    new_book = books_dao.update_book_info(no_none_dict)
    if book.authors is not None and new_book:
        authors = books_dao.get_authors_by_names(book.authors.split(','))
        new_book.authors.set(authors)



# 通过书编号查询书信息
def getBook_by_number(number):
    book_exist = books_dao.judge_book(number)
    if book_exist:
        book_info = books_dao.getBook_by_number(number)
        if book_info:
            return {"book_info": book_info}
        else:
            raise FormException("查询失败")
    else:
        raise FormException("书籍不存在")


# 通过书名查找
def getBook_by_title(book_title):
    book_info = books_dao.getBook_by_title(book_title)
    if book_info:
        return {"book_info": book_info}
    else:
        raise FormException("查询失败或者书名不存在")


# 添加出版社
def add_pub(pubname):
    pub_exist = books_dao.judge_pub(pubname)
    if pub_exist:
        rsp = {
            "code": -200,
            "msg": "出版社已存在"
        }
    else:
        pub_id = books_dao.add_pub(pubname)
        if pub_id:
            msg = "添加成功"
            rsp = {
                "code": 0,
                "msg": msg,
                "pub_id": pub_id
            }
        else:
            rsp = {
                "code": -200,
                "msg": "添加失败",
            }
    return rsp


# 删除出版社
def delete_pub(pub_id):
    rsp = {
        "code": 0,
        "msg": "删除成功"
    }
    flag = books_dao.delete_pub(pub_id)
    if not flag:
        rsp["code"] = -200
        rsp["msg"] = "删除失败"
    return rsp


# 添加作者
def add_author(number, name, company, email):
    author_exist = books_dao.judge_authors(number)
    if author_exist:
        rsp = {
            "code": -200,
            "msg": "作者信息已存在"
        }
    else:
        author_id = books_dao.add_author(number, name, company, email)
        if author_id:
            rsp = {
                "code": 0,
                "msg": "添加作者成功",
                "author_id": author_id
            }
        else:
            rsp = {
                "code": -200,
                "msg": "添加作者失败"
            }
    return rsp


# 删除作者
def delete_author(author_id):
    rsp = {
        "code": 0,
        "msg": "删除成功",
    }
    flag = books_dao.delete_author(author_id)
    if flag:
        rsp["msg"] = flag
    else:
        rsp["code"] = -200
        rsp["msg"] = "作者信息已删除"
    return rsp


# 修改作者
def update_author(author_id, number, name, company, email):
    rsp = {
        "code": 0,
        "msg": "修改成功"
    }
    author_flag = books_dao.update_author(author_id, number, name, company, email)
    if author_flag:
        rsp["author_id"] = author_id
    else:
        rsp["code"] = -200
        rsp["msg"] = "修改失败"
    return rsp


# 通过id查看作者
def getAuthor_by_id(authors_id):
    author = books_dao.getAuthor_by_id(authors_id)
    return getAuthor(author)


# 通过number查看作者
def getAuthor_by_number(authors_number):
    author = books_dao.getAuthor_by_number(authors_number)
    return getAuthor(author)


# 通过name查看作者
def get_author_by_name(authors_name):
    author = books_dao.getAuthor_by_name(authors_name)
    return getAuthor(author)


# 查看作者
def getAuthor(author):
    if author:
        return {"author_info": author}
    else:
        raise FormException("查询失败,老师信息不存在")


def fetch_books(req, user, page, page_size, order_by='pub_date', desc=True, book_id=None, title=None, author=None):
    order_by_allow_set = {'create_time', 'pub_date', 'rate', 'comment_count'}
    offset, limit = page2offset(page, page_size)
    if order_by not in order_by_allow_set:
        raise FormException("不支持的排序字段")
    if page_size > 100:
        raise FormException("单页不能大于100条")

    domain_name = get_current_domain_name(req)

    filter_dict = {}
    if book_id:
        filter_dict['id'] = book_id
    if title:
        filter_dict['title__contains'] = title
    if author:
        filter_dict['authors__name'] = author

    total_count, books = books_dao.fetch_books(offset, limit, order_by, desc, filter_dict)

    book_dicts = [
        {
            "id": book.id, "title": book.title, "price": book.price, "retail_price": book.retail_price,
            "pub": book.pub.pubname, "authors": ','.join([author.name for author in book.authors.all()]),
            "cover_url": get_url(req, book.cover_uri),
            "pub_date": book.pub_date.strftime("%Y-%m-%d"),
            "rate": nround(book.bookcomment__score__avg, 1), "comment_count": book.bookcomment__id__count,
            "describe": book.describe
        }
        for book in books
    ]

    return total_count, book_dicts
